using System;
using System.Collections.Generic;
using COC.CComponent;
using COC.CEvent;
using COC.Character;
using COC.Character.AI.Provider;
using COC.Character.AI.Provider.Animation;
using COC.Character.Extra;
using COC.Constant;
using COC.Content.Task;
using COC.Tools.AI.Motion;
using COC.Window;
using UnityEngine;
using System.Collections;
using Random = UnityEngine.Random;

namespace COC.Internal.Handler
{
    public class SceneResourceHandler : MonoBehaviour
    {

        // Use this for initialization
        SceneManager _scene;
        ParallelTaskCollection pt;
        SerialTaskCollection st;
        public static List<Vector3> path = new List<Vector3>();
        public static List<Vector3> obstacles = new List<Vector3>();
        #region debug inspector
        public bool debug;
        #endregion
        Font ArialFont;
        void Start()
        {
            ArialFont = (Font)Resources.GetBuiltinResource(typeof(Font), "Arial.ttf");
            StartCoroutine(Init());

          
        }
        IEnumerator Init()
        {
            CServiceActivator serviceActivator = this.gameObject.AddComponent<CServiceActivator>();
            st = new SerialTaskCollection();
            st.description = "Downloading resource";
            st.Add(serviceActivator.Init());//start crucial services
            st.Add(InitScene());
            st.Add(InitProviders());
            st.Add(GenerateObstacles());
            st.Add(GenerateEnemys());
            st.Add(PrepareAISteeringAndExtra());
            TaskRunner.Instance.RunManaged(st);
            yield return st;
        }

        private IEnumerator PrepareAISteeringAndExtra()
        {
            ISteeringDriver.SteeringDriverImpl.list.Clear();
            InputEventComponent input=GameObject.FindGameObjectWithTag(CommonConstants.SCENE_MANAGER_TAG).GetComponent<InputEventComponent>();
            input.setEnableInput(true);
            input.enabled = true;
            yield return null;
        }
        private IEnumerator GenerateEnemys()
        {
            GameObject root =GameObject.FindGameObjectWithTag(CommonConstants.ENEMY_ROOT_NAME);
            GameObject enemy = Resources.Load(Characters.Resource.Path.ARCHER) as GameObject;
            enemy.name = "enemy";
            // root.transform.parent = GameObject.FindGameObjectWithTag(CommonConstants.MAIN_PANEL_TAG).transform;
            float times = .01f;
            //float angle = 10;
            Vector3 v3 = Vector3.zero;
            GameObject go;
            float x = 45.0f;
            float angle = 1.0f;
            //float y = 3.0f;
            for (int i = 0; i < 18; i++)
            {
                //v3 = (Quaternion.AngleAxis(Random.Range(-angle, angle), Vector3.up) * new Vector3(Random.Range(-10, 10), 0.3f, Random.Range(-10, 10)));

                v3 = new Vector3(Mathf.Sin(Random.Range(angle, Mathf.PI * 2)) * x, 0.3f, Mathf.Cos(Random.Range(angle, Mathf.PI * 2)) * x);
                go = GameObject.Instantiate(enemy) as GameObject;
                go.name = enemy.name + "(Clone)_" + i;
                go.transform.position += Vector3.up * 5f;
                go.transform.localPosition = new Vector3(v3.x, 0f, v3.z);
                go.transform.localScale = Vector3.one * 5;
                go.renderer.material.color = Color.green;
                go.transform.parent = root.transform;
                go.AddComponent<Rigidbody>().isKinematic = true;


                CharacterProfile profile = go.AddComponent<CharacterProfile>();
                profile.enabled = false;
                BaseModel m = new CharacterProfile.BaseValueModel();
                m.type = Character.Character.HERO_KING;
                profile.setProfile(m.prePlaySate);
                profile._health = new GameObject(go.name+i+ "_health");
                HUDText hUDText = profile._health.AddComponent<HUDText>();
                hUDText.fontStyle = FontStyle.Bold;
                hUDText.fontSize = 40;
                hUDText.trueTypeFont = ArialFont;
                hUDText.Add("Health", Color.magenta, 2f);
                hUDText.gameObject.AddComponent<UIFollowTarget>().target = go.transform;
                profile._aiBehave = go.AddComponent<AIBehave>();
                profile._aiBehave.enabled = false;
                profile._aiBehave.target = GameObject.FindGameObjectWithTag(CommonConstants.PLAYER_NAME).transform;
                profile._aiBehave.path = SceneResourceHandler.path.ToArray();
                profile._aiBehave.currState = FSMState.STANDBY;
                obstacles.Add(v3);
                angle++;

                //flag indicate a player
                profile._aiBehave.playerId = 1;
                profile._aiBehave.enabled = true;
                profile.enabled = true;
                if (Math.Abs(x % 2) < 0)//change arrow
                {
                    x--;

                    continue;
                }

                x++;
                //times++;

            }
            yield return null;
        }

        private IEnumerator GenerateObstacles()
        {
             calculatePath();
            
            yield return null;
            obstacles = ISteeringDriver.getInstance().obstacles;
            genarateObstacles();
            yield return null;
        }
        void genarateObstacles()
        {
            GameObject root=new GameObject(CommonConstants.OBSTACLE_ROOT_NAME);
           // root.transform.parent = GameObject.FindGameObjectWithTag(CommonConstants.MAIN_PANEL_TAG).transform;
            float times = .01f;
            //float angle = 10;
            Vector3 v3 = Vector3.zero;
            GameObject go;
            float x = 45.0f;
            float angle = 1.0f;
            //float y = 3.0f;
            for (int i = 0; i < 18; i++)
            {
                //v3 = (Quaternion.AngleAxis(Random.Range(-angle, angle), Vector3.up) * new Vector3(Random.Range(-10, 10), 0.3f, Random.Range(-10, 10)));

                v3 = new Vector3(Mathf.Sin(Random.Range(angle, Mathf.PI * 2)) * x, 0.3f, Mathf.Cos(Random.Range(angle, Mathf.PI * 2)) * x);
                go = GameObject.CreatePrimitive(PrimitiveType.Capsule);
                obstacles.Add(v3);
                go.transform.localPosition = new Vector3(v3.x, 0f, v3.z);
                go.transform.localScale = Vector3.one * 5;
                go.renderer.material.color = Color.cyan;
                go.transform.parent = root.transform;
                angle++;
                if (Math.Abs(x % 2) < 0)//change arrow
                {
                    x--;

                    continue;
                }

                x++;
                //times++;

            }

        }
        void calculatePath()
        {
            GameObject root = new GameObject("_path");
            //root.transform.parent = GameObject.FindGameObjectWithTag(CommonConstants.MAIN_PANEL_TAG).transform;
            float times = .01f;
            //float angle = 10;
            Vector3 v3 = Vector3.zero;
            GameObject go;
            float x = 15.0f;
            float angle = 1.0f;
            //float y = 3.0f;
            for (int i = 0; i < 8; i++)
            {
                //v3 = (Quaternion.AngleAxis(Random.Range(-angle, angle), Vector3.up) * new Vector3(Random.Range(-10, 10), 0.3f, Random.Range(-10, 10)));

                v3 = new Vector3(Mathf.Sin(Random.Range(angle, Mathf.PI * 2)) * x, 0.3f, Mathf.Cos(Random.Range(angle, Mathf.PI * 2)) * x);
                path.Add(v3);
                go = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                go.transform.position = new Vector3(v3.x, 0f, v3.z);
                go.renderer.material.color = Color.green;
                go.transform.parent = root.transform;
                angle++;
                if (Math.Abs(x % 2) < 0)//change arrow
                {
                    x--;

                    continue;
                }

                x++;
                //times++;

            }
            //Camera.main.transform.LookAt(GameObject.FindGameObjectWithTag(CommonConstants.PLAYER_NAME).transform.position);
            iTween.MoveTo(GameObject.FindGameObjectWithTag(CommonConstants.PLAYER_NAME), iTween.Hash("speed", 10.0f, "path", ((List<Vector3>)path).ToArray(), "delay", .1, "loopType", "pingPong"));


        }
        /// <summary>
        /// initialize of input event
        /// </summary>
        /// <returns></returns>
        IEnumerator InitScene()
        {
          
                
                    _scene = SceneManager.getInstance();
                    predifinePrefab();
                   // _scene.setEnableInput(true);
                       
                
                yield return null;
          
        }
        /// <summary>
        /// load avaliable providers:animation,character profile
        /// </summary>
        /// <returns></returns>
        IEnumerator InitProviders()
        {
            GameObject go = new GameObject(CommonConstants.Provider_MANAGER_TAG);
            go.tag = CommonConstants.Provider_MANAGER_TAG;
            go.AddComponent<AnimationProvider>();
            go.AddComponent<CharacterProfileProvider>();
            DontDestroyOnLoad(go);
            yield return null;
        }

        private void predifinePrefab()
        {
            _scene.predefinePrefabs();
           
        }

        // Update is called once per frame
        void Update()
        {

        }
    }

}